package cn.edu.fzu.delivery.filter;

import static cn.edu.fzu.delivery.common.RetCode.REFUSE_LOGIN;

import java.io.IOException;
import java.util.Objects;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.edu.fzu.delivery.common.Result;
import cn.edu.fzu.delivery.common.RetCode;
import cn.edu.fzu.delivery.domain.entity.Customer;
import cn.edu.fzu.delivery.domain.entity.SysUser;
import cn.edu.fzu.delivery.domain.enums.UserStatusEnum;
import cn.edu.fzu.delivery.domain.enums.UserTypeEnum;
import cn.edu.fzu.delivery.session.SessionConstant;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;

@Component
public class AuthFilter implements Filter {

    private static final Set<String> REFERER      = ImmutableSet.of("http://101.43.44.19/",
            "http://101.43.44.19:8080/");

    //顾客请求路径
    private static final String      CUSTOMER_URI = "/api/auth/customer";

    //系统管理员请求路径
    private static final String      SYS_URI      = "/api/auth/sys";

    //快递员请求路径
    private static final String      DELIVERY_URI = "/api/auth/deliveryman/";

    //网点快递员请求路径
    private static final String      NETWORK_URI  = "/api/auth/networkAdmin/";

    private static final Set<String> ALLOWED_URI  = ImmutableSet.of(
            //获取登陆用户信息
            "/api/auth/getCurrentUserInfo",
            //获取网点列表
            "/api/auth/network/list");

    @Override
    public void init(FilterConfig filterConfig) {
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setHeader("content-type", "application/json");
        resp.setHeader("charset", "UTF-8");

        HttpSession session = req.getSession();
        String uri = req.getRequestURI().replace("/delivery-api-0.0.1-SNAPSHOT", "");

        Object user = session.getAttribute(SessionConstant.DELIVERY_ACCOUNT);

        if (user == null) {
            resp.getWriter().print(JSON.toJSONString(new Result(RetCode.NO_LOGIN, "未登录")));
            return;
        }

        if (user instanceof SysUser) {
            SysUser sysUser = (SysUser) user;
            if (sysUser.getStatus() == UserStatusEnum.BAN || sysUser.getStatus() == UserStatusEnum.DELETE
                    || uri.startsWith(CUSTOMER_URI)) {
                if (!ALLOWED_URI.contains(uri)) {
                    resp.getWriter().print(JSON.toJSONString(new Result(REFUSE_LOGIN, "非法访问")));
                    return;
                }
            }
            //快递员只能访问快递员地址
            if ((sysUser.getType() == UserTypeEnum.EXPRESS && !uri.startsWith(DELIVERY_URI))
                    //网点管理员只能访问网点管理员地址
                    || (sysUser.getType() == UserTypeEnum.NET_ADMIN && !uri.startsWith(NETWORK_URI))
                    //系统管理员只能访问系统管理员地址
                    || (sysUser.getType() == UserTypeEnum.SUPER_ADMIN && !uri.startsWith(SYS_URI))) {
                if (!ALLOWED_URI.contains(uri)) {
                    resp.getWriter().print(JSON.toJSONString(new Result(REFUSE_LOGIN, "非法访问")));
                    return;
                }
            }
        } else {
            Customer customer = (Customer) user;
            if (customer.getStatus() == UserStatusEnum.BAN || customer.getStatus() == UserStatusEnum.DELETE
            //顾客只能访问顾客界面
                    || !uri.startsWith(CUSTOMER_URI)) {
                if (!ALLOWED_URI.contains(uri)) {
                    resp.getWriter().print(JSON.toJSONString(new Result(REFUSE_LOGIN, "非法访问")));
                    return;
                }
            }
        }

        //防止csrf攻击
        //        String referer = req.getHeader("Referer");
        //        boolean flag = false;
        //        if (StringUtils.isNotBlank(referer)) {
        //            for (String ref : REFERER) {
        //                if (referer.startsWith(ref)) {
        //                    flag = true;
        //                    break;
        //                }
        //            }
        //        }
        //        if (!flag) {
        //            resp.getWriter().print(JSON.toJSONString(new Result(RetCode.RESUSE_OPERATOR, "非法操作")));
        //            return;
        //        }

        String reqToken = req.getHeader(SessionConstant.TOKEN);
        String token = (String) session.getAttribute(SessionConstant.TOKEN);
        if (StringUtils.isBlank(reqToken) || !Objects.equals(reqToken, token)) {
            resp.getWriter().print(JSON.toJSONString(new Result(RetCode.RESUSE_OPERATOR, "非法操作")));
            return;
        }

        chain.doFilter(request, response);

    }


    @Override
    public void destroy() {
        // do nothing
    }

}
